package com.crm.business.crm.controller;


import com.alibaba.fastjson.JSONObject;
import com.crm.business.crm.log.CrmReceivablesLog;
import com.crm.business.crm.service.CrmUploadExcelService;
import com.crm.business.crm.service.ICrmReceivablesService;
import com.crm.business.crm.service.IHpPaymentTypeDictService;
import com.crm.business.crm.service.BillPaymentDeptBindService;
import com.crm.common.crm.common.CrmModel;
import com.crm.common.crm.constant.CrmCodeEnum;
import com.crm.common.crm.constant.CrmEnum;
import com.crm.common.crm.constant.FieldEnum;
import com.crm.common.crm.entity.BO.*;
import com.crm.common.crm.entity.PO.CrmReceivables;
import com.crm.common.crm.entity.PO.HpPaymentTypeDict;
import com.crm.common.crm.entity.VO.CrmInfoNumVO;
import com.crm.common.crm.entity.VO.CrmModelFiledVO;
import com.crm.common.crm.entity.VO.PaymentDeptBindVO;
import com.crm.common.ka.core.common.R;
import com.crm.common.ka.core.common.Result;
import com.crm.common.ka.core.common.SubModelType;
import com.crm.common.ka.core.common.log.BehaviorEnum;
import com.crm.common.ka.core.common.log.SysLog;
import com.crm.common.ka.core.common.log.SysLogHandler;
import com.crm.common.ka.core.entity.BasePage;
import com.crm.common.ka.core.exception.CrmException;
import com.crm.common.crm.entity.BO.CrmSearchBO;
import com.crm.common.ka.core.servlet.upload.FileEntity;
import com.crm.business.utils.UserUtil;
import com.crm.common.utils.spring.SpringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 回款表 前端控制器
 * </p>
 *
 * @author zhangzhiwei
 * @since 2020-05-28
 */
@RestController
@RequestMapping("/crmReceivables")
@Api(tags = "回款模块接口")
@SysLog(subModel = SubModelType.CRM_RECEIVABLES,logClass = CrmReceivablesLog.class)
public class CrmReceivablesController {

    @Autowired
    private ICrmReceivablesService crmReceivablesService;

    @PostMapping("/queryPageList")
    @ApiOperation("查询列表页数据")
    public Result<BasePage<Map<String, Object>>> queryPageList(@RequestBody CrmSearchBO search) {
        search.setPageType(1);
        BasePage<Map<String, Object>> mapBasePage = crmReceivablesService.queryPageList(search);
        return R.ok(mapBasePage);
    }

    @PostMapping("/add")
    @ApiOperation("保存数据")
    @SysLogHandler(behavior = BehaviorEnum.SAVE,object = "#crmModel.entity.[number]",detail = "'新增了回款:' + #crmModel.entity.[number]")
    public Result add(@RequestBody CrmContractSaveBO crmModel) {
        crmReceivablesService.addOrUpdate(crmModel);
        return R.ok();
    }

    @PostMapping("/update")
    @ApiOperation("修改数据")
    @SysLogHandler(behavior = BehaviorEnum.UPDATE)
    public Result update(@RequestBody CrmContractSaveBO crmModel) {
        crmReceivablesService.addOrUpdate(crmModel);
        return R.ok();
    }

    @PostMapping("/queryById/{receivablesId}")
    @ApiOperation("根据ID查询")
    public Result<CrmModel> queryById(@PathVariable("receivablesId") @ApiParam(name = "id", value = "id") Integer receivablesId) {
        Integer number = crmReceivablesService.lambdaQuery().eq(CrmReceivables::getReceivablesId,receivablesId).ne(CrmReceivables::getCheckStatus,7).count();
        if (number == 0){
            throw new CrmException(CrmCodeEnum.CRM_DATA_DELETED,"回款");
        }
        CrmModel model = crmReceivablesService.queryById(receivablesId);
        return R.ok(model);
    }

    @PostMapping("/queryReturnTypeById/{receivablesId}")
    @ApiOperation("根据ID查询")
    public Result<CrmModel> queryReturnTypeById(@PathVariable("receivablesId") @ApiParam(name = "id", value = "id") Integer receivablesId) {
        Integer number = crmReceivablesService.lambdaQuery().eq(CrmReceivables::getReceivablesId,receivablesId).ne(CrmReceivables::getCheckStatus,7).count();
        if (number == 0){
            throw new CrmException(CrmCodeEnum.CRM_DATA_DELETED,"回款");
        }
        CrmModel model = crmReceivablesService.queryReturnTypeById(receivablesId);
        return R.ok(model);
    }

    @PostMapping("/field")
    @ApiOperation("查询新增所需字段")
    public Result<List<CrmModelFiledVO>> queryField() {
        List<CrmModelFiledVO> crmModelFiledList = crmReceivablesService.queryField(null);
        return R.ok(crmModelFiledList);
    }

    @PostMapping("/field/{id}")
    @ApiOperation("查询修改数据所需信息")
    public Result<List<CrmModelFiledVO>> queryField(@PathVariable("id") @ApiParam(name = "id", value = "id") Integer id) {
        List<CrmModelFiledVO> crmModelFiledList = crmReceivablesService.queryField(id);
        return R.ok(crmModelFiledList);
    }

    @PostMapping("/deleteByIds")
    @ApiOperation("根据ID删除数据")
    @SysLogHandler(behavior = BehaviorEnum.DELETE)
    public Result deleteByIds(@ApiParam(name = "ids", value = "id列表") @RequestBody List<Integer> ids) {
        crmReceivablesService.deleteByIds(ids);
        return R.ok();
    }

    @PostMapping("/changeOwnerUser")
    @ApiOperation("修改回款负责人")
    @SysLogHandler(behavior = BehaviorEnum.CHANGE_OWNER)
    public Result changeOwnerUser(@RequestBody CrmChangeOwnerUserBO crmChangeOwnerUserBO){
        crmReceivablesService.changeOwnerUser(crmChangeOwnerUserBO.getIds(),crmChangeOwnerUserBO.getOwnerUserId());
        return R.ok();
    }

    @PostMapping("/changeTeacherUser")
    @ApiOperation("修改回款讲师负责人")
    public Result changeTeacherUser(@RequestBody CrmChangeOwnerUserBO crmChangeOwnerUserBO){
        crmReceivablesService.changeTeacherUser(crmChangeOwnerUserBO);
        return R.ok();
    }

    @PostMapping("/information/{id}")
    @ApiOperation("查询详情页信息")
    public Result<List<CrmModelFiledVO>> information(@PathVariable("id") @ApiParam(name = "id", value = "id") Integer id) {
        List<CrmModelFiledVO> information = crmReceivablesService.information(id);
        return R.ok(information);
    }

    @PostMapping("/queryFileList")
    @ApiOperation("查询附件列表")
    public Result<List<FileEntity>> queryFileList(@RequestParam("id") @ApiParam(name = "id", value = "id") Integer id) {
        List<FileEntity> fileEntities = crmReceivablesService.queryFileList(id);
        return R.ok(fileEntities);
    }

    @PostMapping("/num")
    @ApiOperation("详情页数量展示")
    public Result<CrmInfoNumVO> num(@RequestParam("id") @ApiParam(name = "id", value = "id") Integer id) {
        CrmInfoNumVO infoNumVO = crmReceivablesService.num(id);
        return R.ok(infoNumVO);
    }

    @PostMapping("/batchExportExcel")
    @ApiOperation("选中导出")
    @SysLogHandler(behavior = BehaviorEnum.EXCEL_EXPORT,object = "回款导出",detail = "选中导出")
    public void batchExportExcel(@RequestBody @ApiParam(name = "ids", value = "id列表") List<Integer> ids, HttpServletResponse response) {
        CrmSearchBO search = new CrmSearchBO();
        search.setPageType(10000);
        search.setLabel(CrmEnum.RECEIVABLES.getType());
        CrmSearchBO.Search entity = new CrmSearchBO.Search();
        entity.setFormType(FieldEnum.TEXT.getFormType());
        entity.setSearchEnum(CrmSearchBO.FieldSearchEnum.ID);
        entity.setValues(ids.stream().map(Object::toString).collect(Collectors.toList()));
        search.getSearchList().add(entity);
        search.setPageType(10000);
        crmReceivablesService.exportExcel(response, search);
    }

    @PostMapping("/allExportExcel")
    @ApiOperation("全部导出")
    @SysLogHandler(behavior = BehaviorEnum.EXCEL_EXPORT,object = "回款导出",detail = "全部导出")
    public void allExportExcel(@RequestBody CrmSearchBO search, HttpServletResponse response) {
        search.setPageType(10000);
        crmReceivablesService.exportExcel(response, search);
    }

    @PostMapping("/updateInformation")
    @ApiOperation("基本信息保存修改")
    @SysLogHandler(behavior = BehaviorEnum.UPDATE)
    public Result updateInformation(@RequestBody CrmUpdateInformationBO updateInformationBO) {
        crmReceivablesService.updateInformation(updateInformationBO);
        return R.ok();
    }

    @PostMapping("/queryKPI")
    @ApiOperation("综合统计 回款业务")
    public Result<BasePage<Map<String, Object>>> queryKPI(int num , int start, int end, String year) {    //start = 开始期数   end = 结束期数
        //num   10 = KPI
        CrmSearchBO search = new CrmSearchBO();
        search.setSearch("");
        CrmSearchBO.Search obj = new CrmSearchBO.Search();
        CrmSearchBO.Search obj1 = new CrmSearchBO.Search();
        search.setPageType(1);
        search.getSearchList().add(0,obj);
        search.getSearchList().add(1,obj1);
        if(num == 10) {
            //KPI (回款审核状态已通过)
            search.getSearchList().get(0).setName("checkStatus");
            search.getSearchList().get(0).setFormType("checkStatus");
            search.getSearchList().get(0).setSearchEnum(CrmSearchBO.FieldSearchEnum.IS);
            search.getSearchList().get(0).setScript(null);
            List<String> list = new ArrayList<>();
            list.add(0, "1");
            search.getSearchList().get(0).setValues(Collections.singletonList(list.get(0)));
        }
        if(start != -1 & end != -1) {
            //训练营期数(start,end)
            search.getSearchList().get(1).setName("trainingPeriods");
            search.getSearchList().get(1).setFormType("number_input");
            search.getSearchList().get(1).setScript(null);
            search.getSearchList().get(1).setSearchEnum(CrmSearchBO.FieldSearchEnum.IS);
            int len = end - start + 1;
            int arrayNum[] = new int[len];
            for (int i = start, j = 0; i <= end; i++, j++) {
                //int j=1; j++;
                arrayNum[j] = i;
            }
            List<String> resList = new ArrayList<>();
            for (int n = 1, j = 0; n <= len; n++, j++) {
                resList.add(j, String.valueOf(arrayNum[j]));
            }
            search.getSearchList().get(1).setValues(resList);
        }else if(start == -1 & end == -1) {  //根据年份查询
            if (year != null) {
                //用户指定年份
                String startYear = year + "-01-01 00:00:00";
                String endYear = year + "-12-31 23:59:59";
                search.getSearchList().get(1).setName("createTime");
                search.getSearchList().get(1).setFormType("datetime");
                search.getSearchList().get(1).setSearchEnum(CrmSearchBO.FieldSearchEnum.DATE_TIME);
                List<String> yearList=new ArrayList<>();
                yearList.add(0,startYear);
                yearList.add(1,endYear);
                search.getSearchList().get(1).setValues(yearList);

            } else if (year == null) {
                LocalDate today = LocalDate.now();
                String oldDay = null;
                for(long i = 1L;i < 12L; i++){
                    LocalDate localDate = today.minusMonths(i);
                    oldDay = localDate.toString().substring(0,7);
                }
                String endYear = today + " 23:59:59";
                String startYear = oldDay+ "-01 00:00:00";
                search.getSearchList().get(1).setName("createTime");
                search.getSearchList().get(1).setFormType("datetime");
                search.getSearchList().get(1).setSearchEnum(CrmSearchBO.FieldSearchEnum.DATE_TIME);
                List<String> yearList=new ArrayList<>();
                yearList.add(0,startYear);
                yearList.add(1,endYear);
                search.getSearchList().get(1).setValues(yearList);
            }
    }
        BasePage<Map<String, Object>> mapBasePage = crmReceivablesService.queryPageList(search);
        return R.ok(mapBasePage);
    }

    @Autowired
    private IHpPaymentTypeDictService paymentTypeDictService;
    @Autowired
    private BillPaymentDeptBindService wkPaymentDeptBindService;

    @PostMapping("/queryPaymentTypeDicList")
    @ApiOperation("查询列表页数据")
    public Result<String> queryPaymentTypeDicList() {
        List<HpPaymentTypeDict> mapBasePage = paymentTypeDictService.queryPaymentTypeDicListByParentId(0);
        return R.ok(JSONObject.toJSONString(mapBasePage));
    }

    @PostMapping("/paymentDeptBindList")
    @ApiOperation("查询付款方式与部门绑定列表")
    public Result<List<PaymentDeptBindVO>> paymentDeptBindList(@RequestParam("deptId") Integer deptId) {
        List<PaymentDeptBindVO> voList = wkPaymentDeptBindService.paymentDeptBindList(deptId);
        return R.ok(voList);
    }

    @PostMapping("/paymentDeptBind")
    @ApiOperation("付款方式与部门绑定")
    public Result<Integer> paymentDeptBindList(@RequestParam("deptId") Integer deptId, @RequestBody List<Integer> list) {
        Integer i = wkPaymentDeptBindService.paymentDeptBind(deptId,list);
        return R.ok(i);
    }

    @PostMapping("/queryOverdueStatus")
    @ApiOperation("获取逾期状态信息")
    public Result queryOverdueStatus(){
        List<String> options = this.crmReceivablesService.queryOverdueStatus();
        return Result.ok(options);
    }

    @PostMapping("/queryReceivablesByContractId")
    @ApiOperation("详情页数量展示")
    public Result<CrmInfoNumVO> queryReceivablesByContractId(@RequestParam("id") @ApiParam(name = "id", value = "id") Integer id) {
        CrmInfoNumVO infoNumVO = crmReceivablesService.num(id);
        return R.ok(infoNumVO);
    }

    @PostMapping("/receivablesPlanCheckStatus")
    @ApiOperation("还款计划审核通过")
    public Result checkStatus(@RequestParam("id") @ApiParam(name = "id", value = "id") Integer id){
        this.crmReceivablesService.checkStatus(id);
        return Result.ok();
    }

    @PostMapping("/downloadExcel")
    @ApiOperation("下载导入模板")
    public void downloadExcel(HttpServletResponse response) throws IOException {
        crmReceivablesService.downloadExcel(response);
    }

    @PostMapping("/uploadExcel")
    @ApiOperation("导入账单分期回款")
    @SysLogHandler(behavior = BehaviorEnum.EXCEL_IMPORT,object = "导入账单分期回款",detail = "导入逾期")
    public Result<Long> uploadExcel(@RequestParam("file") MultipartFile file, @RequestParam("ownerUserId") Long ownerUserId, @RequestParam("repeatHandling") Integer repeatHandling) {
        UploadExcelBO uploadExcelBO = new UploadExcelBO();
        uploadExcelBO.setOwnerUserId(ownerUserId);
        uploadExcelBO.setUserInfo(UserUtil.getUser());
        uploadExcelBO.setCrmEnum(CrmEnum.RECEIVABLES);
        uploadExcelBO.setPoolId(null);
        uploadExcelBO.setRepeatHandling(repeatHandling);
        Long messageId = SpringUtils.getBean(CrmUploadExcelService.class).uploadExcel(file, uploadExcelBO);
        return R.ok(messageId);
    }

}

